import logging
from django.conf import settings
from dashscope.audio.asr import Recognition, RecognitionCallback, RecognitionResult
import dashscope
import time

logger = logging.getLogger(__name__)

class SpeechRecognitionCallback(RecognitionCallback):
    def __init__(self):
        super().__init__()
        self.result_text = ""
        self.is_finished = False
        self.error = None
        self.is_started = False
        self.final_result = None  # 添加最终结果存储
        
    def on_open(self):
        logger.info("语音识别连接已打开")
        self.is_started = True
        
    def on_close(self):
        logger.info("语音识别连接已关闭")
        self.is_finished = True
        
    def on_error(self, error):
        logger.error(f"语音识别错误: {error}")
        self.error = error
        self.is_finished = True
        
    def on_event(self, result):
        if isinstance(result, RecognitionResult):
            sentence = result.get_sentence()
            if sentence and isinstance(sentence, dict):
                # 只在句子结束时更新最终结果
                if sentence.get('sentence_end') and sentence.get('text'):
                    self.final_result = sentence['text'].strip()
                    self.result_text = self.final_result
                logger.info(f"识别结果: {sentence}")

class SpeechRecognitionHandler:
    def __init__(self):
        self.config = settings.SPEECH_RECOGNITION_CONFIG
        if not self.config['API_KEY'].startswith('sk-'):
            raise ValueError('API Key 格式错误，必须以 sk- 开头')
        dashscope.api_key = self.config['API_KEY']
        
    def process_audio(self, audio_data):
        """处理音频数据并返回识别结果"""
        try:
            # 验证API Key
            if not dashscope.api_key:
                logger.error("API Key未设置")
                return {
                    'success': False,
                    'error': 'API Key未正确配置'
                }
            
            # 创建回调对象
            callback = SpeechRecognitionCallback()
            
            # 创建识别对象
            try:
                recognition = Recognition(
                    model=self.config['MODEL'],
                    callback=callback,
                    format=self.config['FORMAT'],
                    sample_rate=self.config['SAMPLE_RATE']
                )
            except Exception as e:
                logger.error(f"创建识别对象失败: {str(e)}")
                if '401' in str(e) or 'Unauthorized' in str(e):
                    return {
                        'success': False,
                        'error': 'API Key无效，请检查配置'
                    }
                return {
                    'success': False,
                    'error': f'创建识别对象失败: {str(e)}'
                }
            
            logger.info(f"开始语音识别，使用模型: {self.config['MODEL']}")
            
            # 启动识别
            try:
                recognition.start()
            except Exception as e:
                logger.error(f"启动识别失败: {str(e)}")
                return {
                    'success': False,
                    'error': f'启动识别失败: {str(e)}'
                }
            
            # 等待连接建立
            start_wait = time.time()
            while not callback.is_started and (time.time() - start_wait) < 5:
                time.sleep(0.1)
                
            if not callback.is_started:
                logger.error("语音识别连接未能成功建立")
                return {
                    'success': False,
                    'error': '语音识别服务连接失败，请检查网络连接'
                }
            
            # 发送音频数据
            try:
                recognition.send_audio_frame(audio_data)
                logger.info(f"已发送音频数据，大小: {len(audio_data)} 字节")
            except Exception as e:
                logger.error(f"发送音频数据失败: {str(e)}")
                return {
                    'success': False,
                    'error': f'发送音频数据失败: {str(e)}'
                }
            
            # 等待识别完成
            max_wait_time = 15
            start_time = time.time()
            
            while not callback.is_finished and (time.time() - start_time) < max_wait_time:
                if callback.final_result:  # 使用 final_result 检查
                    break
                time.sleep(0.1)
            
            try:
                recognition.stop()
                logger.info("语音识别已停止")
            except Exception as e:
                logger.error(f"停止识别时出错: {str(e)}")
            
            if callback.error:
                logger.error(f"语音识别出错: {callback.error}")
                error_msg = str(callback.error)
                if '401' in error_msg or 'Unauthorized' in error_msg:
                    return {
                        'success': False,
                        'error': 'API Key无效，请检查配置'
                    }
                return {
                    'success': False,
                    'error': error_msg
                }
                
            if callback.final_result:  # 使用 final_result 返回结果
                logger.info(f"语音识别成功: {callback.final_result}")
                return {
                    'success': True,
                    'text': callback.final_result
                }
            else:
                logger.warning("语音识别未返回文本结果")
                return {
                    'success': False,
                    'error': '未能识别出文字，请说话时间稍长一些，或靠近麦克风说话'
                }
                
        except Exception as e:
            logger.error(f"语音识别处理错误: {str(e)}", exc_info=True)
            error_msg = str(e)
            if '401' in error_msg or 'Unauthorized' in error_msg:
                return {
                    'success': False,
                    'error': 'API Key无效，请检查配置'
                }
            return {
                'success': False,
                'error': error_msg
            } 